﻿using System;
using System.Globalization;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
namespace YanZhiwei.DotNet2.Utilities.Common
{
    /// <summary>
    /// Number帮助类
    /// </summary>
    public static class NumberHelper
    {
        #region 是否是大于等于零的整数
        /// <summary>
        /// 是否是大于等于零的整数
        /// </summary>
        /// <param name="item">需要判断项</param>
        /// <returns>是否是大于等于零的整数</returns>
        public static bool IsNaturalNumber(string item)
        {
            Regex _notNaturalPattern = new Regex("[^0-9]");
            Regex _naturalPattern = new Regex("0*[1-9][0-9]*");
            return !_notNaturalPattern.IsMatch(item) && _naturalPattern.IsMatch(item);
        }
        #endregion 
        #region 是否是正整数
        /// <summary>
        /// 是否是正整数
        /// </summary>
        /// <param name="item">需要判断项</param>
        /// <returns>是否是正整数</returns>
        public static bool IsWholeNumber(string item)
        {
            Regex _notWholePattern = new Regex("[^0-9]");
            return !_notWholePattern.IsMatch(item);
        }
        #endregion 
        #region 是否是正整数或负整数
        /// <summary>
        /// 是否是正整数或负整数
        /// </summary>
        /// <param name="item">需要判断项</param>
        /// <returns>是否是正整数或负整数</returns>
        public static bool IsInteger(string item)
        {
            Regex notIntPattern = new Regex("[^0-9-]");
            Regex intPattern = new Regex("^-[0-9]+$|^[0-9]+$");
            return !notIntPattern.IsMatch(item) && intPattern.IsMatch(item);
        }
        #endregion 
        #region 是否是数字
        /// <summary>
        /// 是否是数字
        /// </summary>
        /// <param name="item">需要判断项</param>
        /// <returns>是否是数字</returns>
        public static bool IsNumber(string item)
        {
            double _result;
            return (double.TryParse(item, NumberStyles.Float, NumberFormatInfo.CurrentInfo, out _result));
        }
        #endregion 
        #region 是否是偶数
        /// <summary>
        /// 是否是偶数
        /// </summary>
        /// <param name="value">需要判断项</param>
        /// <returns>是否是偶数</returns>
        public static bool IsEven(int value)
        {
            return ((value & 1) == 0);
        }
        #endregion 
        #region 是否是奇数
        /// <summary>
        /// 是否是奇数
        /// </summary>
        /// <param name="value">需要判断项</param>
        /// <returns>是否是奇数</returns>
        public static bool IsOdd(int value)
        {
            return ((value & 1) == 1);
        }
        #endregion 
        #region 产生随机数
        /// <summary>
        /// 产生随机数
        /// </summary>
        /// <param name="noZeros">是否包括0</param>
        /// <returns>随机数</returns>
        public static int Random(bool noZeros)
        {
            byte[] _random = new Byte[1];
            RNGCryptoServiceProvider _rng = new RNGCryptoServiceProvider();
            if (noZeros)
            {
                _rng.GetNonZeroBytes(_random);
            }
            else
            {
                _rng.GetBytes(_random);
            }
            return _random[0];
        }
        #endregion 
        #region 生成随机数【包括下限】
        /// <summary>
        /// 生成随机数【包括下限】
        /// </summary>
        /// <param name="high">随机数上限</param>
        /// <returns>随机数</returns>
        public static int Random(int high)
        {
            byte[] random = new Byte[4];
            new RNGCryptoServiceProvider().GetBytes(random);
            int randomNumber = BitConverter.ToInt32(random, 0);
            return Math.Abs(randomNumber % high);
        }
        #endregion 
        #region 生成随机数【包括上下限】
        /// <summary>
        /// 生成随机数【包括上下限】
        /// </summary>
        /// <param name="low">下限</param>
        /// <param name="high">上线</param>
        /// <returns>随机数</returns>
        public static int Random(int low, int high)
        {
            return new Random().Next(low, high);
        }
        #endregion 
        #region 生成double类型的随机数
        /// <summary>
        ///生成double类型的随机数
        /// </summary>
        /// <returns>double类型的随机数</returns>
        public static double Random()
        {
            return new Random().NextDouble();
        }
        #endregion 
        #region 转换为int，如不能转换返回0
        /// <summary>
        /// 转换为int，如不能转换返回0
        /// </summary>
        /// <param name="src">操作值</param>
        /// <returns>转换值</returns>
        public static int GetVal(object src)
        {
            int _val = 0;
            if (null != src)
            {
                int.TryParse(src.ToString(),
                    NumberStyles.AllowThousands | NumberStyles.AllowLeadingWhite
                    | NumberStyles.AllowTrailingWhite | NumberStyles.AllowTrailingSign
                    | NumberStyles.AllowLeadingSign, CultureInfo.CurrentUICulture, out _val);
            }
            return _val;
        }
        #endregion 
        #region 转换为int，如不能转换返回给定的值
        /// <summary>
        /// 转换为int，如不能转换返回给定的值
        /// </summary>
        /// <param name="src">操作值</param>
        /// <param name="defaultVal">给定值</param>
        /// <returns>转换值</returns>
        public static int GetVal(object src, int defaultVal)
        {
            int val = 0;
            if (null != src)
                if (!int.TryParse(src.ToString(), out val))
                    val = defaultVal;
            return val;
        }
        #endregion 
        #region 转换为byte，如不能转换返回0
        /// <summary>
        /// 转换为byte，如不能转换返回0
        /// </summary>
        /// <param name="src">操作值</param>
        /// <returns>转换值</returns>
        public static byte GetByte(object src)
        {
            byte _val = 0;
            if (null != src)
                byte.TryParse(src.ToString(), out _val);
            return _val;
        }
        #endregion 
        #region 转换为byte，如不能转换返给定的值
        /// <summary>
        /// 转换为byte，如不能转换返给定的值
        /// </summary>
        /// <param name="src">操作值</param>
        /// <param name="defaultVal">给定值</param>
        /// <returns>转换值</returns>
        public static byte GetByte(object src, byte defaultVal)
        {
            byte val = defaultVal;
            if (null != src)
                if (!byte.TryParse(src.ToString(), out val))
                    val = defaultVal;
            return val;
        }
        #endregion 
        #region  转换为decimal，如不能转换返回0
        /// <summary>
        /// 转换为decimal，如不能转换返回0
        /// </summary>
        /// <param name="src">操作值</param>
        /// <returns>转换值</returns>
        public static decimal GetDecimal(object src)
        {
            decimal _val = 0;
            if (null != src)
                decimal.TryParse(src.ToString(), out _val);
            return _val;
        }
        #endregion 
        #region 转换为double，如不能转换返回0
        /// <summary>
        /// 转换为double，如不能转换返回0
        /// </summary>
        /// <param name="src">操作值</param>
        /// <returns>转换值</returns>
        public static double GetDouble(object src)
        {
            double val = 0;
            if (null != src)
                double.TryParse(src.ToString(), out val);
            return val;
        }
        #endregion 
        #region 自动累加流水号
        /// <summary>
        /// 自动累加流水号
        /// 自動累加Index, 如果string尾是数字会依序自动累加，若末尾一位不是数字则自动添加数字
        /// eg:
        /// abcd2-->abcd3
        /// 参考链接：http://www.dotblogs.com.tw/neptunic/archive/2010/12/26/autoincrementindex.aspx
        /// </summary>
        /// <param name="Input">流水号</param>
        /// <returns>自动累加流水号</returns>
        public static string AutoIncrementIndex(string Input)
        {
            int _numberIndex = 0;
            int _checkIndex = 1;
            foreach (char c in Input)
            {
                if (!char.IsNumber(c))
                {
                    _numberIndex = _checkIndex;
                }
                _checkIndex++;
            }
            string _numbers = (_numberIndex == Input.Length) ? "" : Input.Substring(_numberIndex, Input.Length - _numberIndex);
            return (_numbers == "") ?
                string.Format("{0}1", Input) :
                string.Format("{0}{1}", Input.Remove(_numberIndex), (Convert.ToInt64(_numbers) + 1).ToString().PadLeft(Input.Length - _numberIndex, '0'));
        }
        #endregion 
        #region 计算百分比保留两位小数
        /// <summary>
        ///计算百分比保留两位小数 
        /// </summary>
        /// <param name="number">除数</param>
        /// <param name="dividendValue">被除数</param>
        /// <returns>百分比;eg:99.7%</returns>
        public static string ToPercent(int number, int dividendValue)
        {
            if (dividendValue > 0)
                return ((float)number / (float)dividendValue * 100).ToString("0.00 ") + "% ";
            else
                return "0.00 %";
        }
        #endregion
    }
}